#! /bin/bash

# preliminary variables
BINARY_DIR="$(pwd)"
RSOURCE_DIR="$( dirname "$0" )"
SOURCE_DIR="$(cd "$( dirname "$0" )" && pwd)"
CONFIG_DIR="$SOURCE_DIR/_config"

# include configuration library
source $CONFIG_DIR/fenzi_conf_lib

# include configuration options
source $CONFIG_DIR/fenzi_conf_options

fenzi_usage() {
    echo "$0 [options]"
    echo
    echo "options:"
    echo
    usage $1
}

parse_command_line OPT "$@"

if (($OPT_long_help)); then
    fenzi_usage OPT
    exit 1
else
    if [ "$BINARY_DIR" = "$SOURCE_DIR" ]; then
        echo
        echo "WARNING: in-source build detected."
        echo "In-source builds are not supported."
        echo
        echo -n "Are you sure you want to continue? [y/N] "
        read ans
        if [ '!' "$ans" = "y" ] &&
           [ '!' "$ans" = "Y" ]; then

           echo
           echo "Configuration cancelled"
           echo 
           echo "Run configure from a different directory, or use install.com"
           echo

           exit 1
        fi
    fi
fi

if (($OPT_long_pconst)); then
    setvar FENZI_PCONST 1
else
    setvar FENZI_PCONST 0
fi

if (($OPT_long_npt)); then
    setvar FENZI_PCONST 1
    setvar FENZI_NPT 1
else
    setvar FENZI_NPT 0
fi

if (($OPT_long_consfix)); then
    setvar FENZI_CONSFIX 1
else
    setvar FENZI_CONSFIX 0
fi

setvar - BUILD "$OPT_long_build"

if [ "$BUILD" = "DEBUG" ]; then
    list append DEFINITIONS DEBUG
    list append COMPILER_FLAGS g
elif [ "$BUILD" = "RELEASE" ]; then
    list append DEFINITIONS NDEBUG
    list append COMPILER_FLAGS O2
fi

setvar INSTALL_PREFIX "$OPT_long_prefix"
setvar - CUDA_ARCHITECTURE "$OPT_long_cudarch"

setvar FENZI_VERSION_MAJOR  2
setvar FENZI_VERSION_MINOR 00

setvar TARGET "${BINARY_DIR}/fenzi_${FENZI_VERSION_MAJOR}_${FENZI_VERSION_MINOR}"

setvar - FENZI_SYSTEM_SIZE "$( toupper "$OPT_long_tssize" )"

#  .-------------------------------------------------.
#  |               PARAMETER TABLE                   |
#  |-------------------------------------------------|
#  |                 VSMALL SMALL MEDIUM LARGE   CCO |
#  | CELL_BLOCKSIZE      96   128    128   256   256 |
#  | CELL_ATOMS          96   128    128   256   256 |
#  |                                                 |
#  | MAX_DIHED_TYPE      64    64     64    64   484 |
#  | MAX_ANGLE_TYPE      64    64     64    64   318 |
#  | MAX_BOND_TYPE       64    64     64    64   256 |
#  '-------------------------------------------------'

if   [ "$FENZI_SYSTEM_SIZE" = "VSMALL" ]; then
    setvar FENZI_CELL_BLOCKSIZE  96
    setvar FENZI_CELL_ATOMS      96
    setvar FENZI_MAX_DIHED_TYPE  64
    setvar FENZI_MAX_ANGLE_TYPE  64
    setvar FENZI_MAX_BOND_TYPE   64
elif [ "$FENZI_SYSTEM_SIZE" = "SMALL"  ]; then
    setvar FENZI_CELL_BLOCKSIZE 128
    setvar FENZI_CELL_ATOMS     128
    setvar FENZI_MAX_DIHED_TYPE  64
    setvar FENZI_MAX_ANGLE_TYPE  64
    setvar FENZI_MAX_BOND_TYPE   64
elif [ "$FENZI_SYSTEM_SIZE" = "MEDIUM" ]; then
    setvar FENZI_CELL_BLOCKSIZE 256
    setvar FENZI_CELL_ATOMS     256
    setvar FENZI_MAX_DIHED_TYPE  64
    setvar FENZI_MAX_ANGLE_TYPE  64
    setvar FENZI_MAX_BOND_TYPE   64
elif [ "$FENZI_SYSTEM_SIZE" = "LARGE"  ]; then
    setvar FENZI_CELL_BLOCKSIZE 256
    setvar FENZI_CELL_ATOMS     256
    setvar FENZI_MAX_DIHED_TYPE  64
    setvar FENZI_MAX_ANGLE_TYPE  64
    setvar FENZI_MAX_BOND_TYPE   64
elif [ "$FENZI_SYSTEM_SIZE" = "CCO"    ]; then
    setvar FENZI_CELL_BLOCKSIZE 256
    setvar FENZI_CELL_ATOMS     256
    setvar FENZI_MAX_DIHED_TYPE 484
    setvar FENZI_MAX_ANGLE_TYPE 318
    setvar FENZI_MAX_BOND_TYPE  256
elif [ "$FENZI_SYSTEM_SIZE" = "CUSTOM" ]; then
    setvar - FENZI_CELL_BLOCKSIZE  "$OPT_long_cblock"
    setvar - FENZI_CELL_ATOMS      "$OPT_long_catoms"
    setvar - FENZI_MAX_DIHED_TYPE  "$OPT_long_maxdtype"
    setvar - FENZI_MAX_ANGLE_TYPE  "$OPT_long_maxatype"
    setvar - FENZI_MAX_BOND_TYPE   "$OPT_long_maxbtype"
fi

setvar - FENZI_MAX_NB      "$OPT_long_maxnb"
setvar - FENZI_MAX_LATTICE "$OPT_long_maxlatt"

list append INSTALL_LIST \
"$BINARY_DIR/fenzi_"\
"${FENZI_VERSION_MAJOR}_"\
"${FENZI_VERSION_MINOR},"\
"${INSTALL_PREFIX}/bin"

list push C_INCLUDE_PATH "${BINARY_DIR}"

list uniq C_INCLUDE_PATH C_INCLUDE_PATH
setvar INCLUDES "$( list cat C_INCLUDE_PATH | 
                    while read -r LL; do echo -I"$LL"; done )"

list uniq COMPILER_FLAGS COMPILER_FLAGS
setvar COMPILER_FLAGS "$( list cat COMPILER_FLAGS | 
                          while read -r LL; do echo -"$LL"; done )"

list uniq DEFINITIONS DEFINITIONS
setvar DEFINITIONS "$( list cat DEFINITIONS | 
                       while read -r LL; do echo -D"$LL"; done )"

find_component make mkdir cc cp cxx cuda rm

configure_file "${SOURCE_DIR}/defs.in.h" \
               "${BINARY_DIR}/defs.h"

configure_file "${SOURCE_DIR}/Makefile.in" \
               "${BINARY_DIR}/Makefile2"

( echo "install:"
    for LL in $( list cat INSTALL_LIST ); do
        SRC="$( echo "$LL" | cut -d , -f 1 )"
        DES="$( echo "$LL" | cut -d , -f 2 )"

        printf "\t${MKDIR} -p \"$DES\" ; ${CP} \"${SRC}\" \"${DES}\"\n"
    done

  echo "uninstall:"
    for LL in $( list cat INSTALL_LIST ); do
        SRC="$( echo "$LL" | cut -d , -f 1 )"
        DES="$( echo "$LL" | cut -d , -f 2 )"

        printf "\t${RM} -f \"${DES}/$(basename ${SRC})\"\n"
    done
) > "${BINARY_DIR}/Makefile.install"

cat << EOF > "${BINARY_DIR}/Makefile"
MAKE="$MAKE"
SRCDIR="$SOURCE_DIR"
BINDIR="$BINARY_DIR"

all:
	\${MAKE} -C \${SRCDIR} -f \${BINDIR}/Makefile2 all
%:
	\${MAKE} -C \${SRCDIR} -f \${BINDIR}/Makefile2 "\$@"
EOF

disp BUILD SOURCE_DIR BINARY_DIR              \
     INSTALL_PREFIX MAKE NVCC CC CXX          \
     FENZI_VERSION_MAJOR FENZI_VERSION_MINOR  \
     FENZI_SYSTEM_SIZE FENZI_CELL_BLOCKSIZE   \
     FENZI_CELL_ATOMS FENZI_MAX_DIHED_TYPE    \
     FENZI_MAX_ANGLE_TYPE FENZI_MAX_BOND_TYPE \
     FENZI_MAX_NB FENZI_MAX_LATTICE           \
     FENZI_PCONST FENZI_NPT                   \
     FENZI_CONSFIX


